#include "sk_storage/lru_cache.hpp"

namespace sk_storage {

LRUCacheOptions::LRUCacheOptions() { capacity = 20000; }

LRUCache::LRUCache(const LRUCacheOptions &opt) { capacity = opt.capacity; }

std::string LRUCache::Get(const std::string &key) {
  auto it = hash_.find(key);
  if (it == hash_.end()) {
    return "";
  }
  auto list_it = it->second;
  auto cache_item = *list_it;
  lru_cache_.erase(list_it);
  lru_cache_.push_front(cache_item);
  it->second = lru_cache_.begin();
  return cache_item.second;
}

void LRUCache::Put(const std::string &key, const std::string &value) {
  auto it = hash_.find(key);
  if (it == hash_.end()) {
    lru_cache_.push_front({key, value});
    hash_[key] = lru_cache_.begin();
  } else {
    auto list_it = it->second;
    auto cache_item = *list_it;
    lru_cache_.erase(list_it);
    cache_item.second = value;
    lru_cache_.push_front(cache_item);
    it->second = lru_cache_.begin();
  }
  if (lru_cache_.size() > capacity) {
    hash_.erase(lru_cache_.back().first);
    lru_cache_.pop_back();
  }
}

} // namespace sk_storage
